import { useEffect, useState } from 'react';
// @ts-ignore
import request from '#/utils/requestAbort';
import { HttpCode } from '#/utils/contacts.js';
import _ from 'lodash';

/**
 * 用于进入页面促使话前查询交易单元后在去查询
 */
const defaultPowerUrl = '';

function getStations(arr: PowerResType[], marketId: string): StationType[];
function getStations(arr: PowerResType[], marketId: string, groupId: string): TreeDatatype[];
function getStations(
  arr: PowerResType[],
  marketId: string,
  groupId?: string,
): StationType[] | TreeDatatype[] {
  const stations = [];
  for (let i = 0; i < arr.length; i++) {
    const n = arr[i];
    if (groupId && groupId === n.groupId && n.marketId === marketId) {
      stations.push({
        title: n.stationName,
        key: n.stationId,
      });
    }
    if (!groupId && n.marketId === marketId) {
      stations.push({
        stationId: n.stationId,
        stationName: n.stationName,
        stationType: n.stationType,
      });
    }
  }

  return _.uniqBy(stations, groupId ? 'key' : 'stationId');
}

function getTreeDataChild(arr: PowerResType[], marketId: string): TreeDatatype[] {
  const treeData: TreeDatatype[] = [];
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i];
    const key = `${item.marketId}-${item.groupId}`;
    const index = _.findIndex(treeData, (n: any) => n.key === key);
    if (item.marketId === marketId && index < 0) {
      treeData.push({
        title: item.groupName,
        key: key,
        children: getStations(arr, marketId, item.groupId),
      });
    }
  }
  return treeData;
}

function convertResult(
  list: PowerResType[],
  convertResult: '1' | '2',
): { provinceArr: ProvinceType[]; treeData: TreeDatatype[] } {
  const provinceArr: ProvinceType[] = [];
  const treeData: any[] = [];
  for (let i = 0; i < list.length; i++) {
    const item = list[i];
    const index = _.findIndex(provinceArr, (n: ProvinceType) => n.value === item.marketId);
    if (index < 0) {
      provinceArr.push({
        provinceName: item.provinceName,
        provinceId: item.provinceId,
        value: item.marketId,
        label: item.marketName,
        stations: getStations(list, item.marketId),
      });

      if (convertResult === '2') {
        treeData.push({
          title: item.marketName,
          key: item.marketId,
          children: getTreeDataChild(list, item.marketId),
        });
      }
    }
  }

  return {
    provinceArr,
    treeData,
  };
}

function getDefaultParams(
  matchFirst: useRequestPowerAfterInitOptinos['matchFirst'],
  data: any[],
): any {
  if (_.isNumber(matchFirst)) {
    return data[matchFirst as number] || undefined;
  }
  if (_.isFunction(matchFirst)) {
    return (matchFirst as Fn)(data);
  }
}

function useRequestPowerAfterInit(
  powerUrl?: string,
  callback?: Fn,
  options?: useRequestPowerAfterInitOptinos,
) {
  const [initLoading, setInitLoading] = useState<boolean>(false);
  const [initResult, setInitResult] = useState<PowerResType[]>([]);
  const [province, setProvince] = useState<ProvinceType[]>([]);
  const [errorMsg, setErrorMsg] = useState<string>();
  const [defaultItem, setDefaultItem] = useState<any>();
  const [treeData, setTreeData] = useState<TreeDatatype[]>([]);

  const init = () => {
    setInitLoading(true);
    const url = powerUrl ? powerUrl : defaultPowerUrl;

    request(url)
      .then((res: any) => {
        if (res.statusCode && res.statusCode === HttpCode.SUCCESS) {
          const data: any[] = _.get(res, 'data', _.get(res, 'json', []));
          if (data.length > 0) {
            const matchFirst: useRequestPowerAfterInitOptinos['matchFirst'] = _.get(
              options,
              'matchFirst',
              0,
            );

            if (!options?.convertResult || options?.convertResult === '0') {
              const defaultParams = getDefaultParams(matchFirst, data);
              callback && callback(defaultParams);
              setDefaultItem(defaultParams);
            } else {
              const { provinceArr, treeData } = convertResult(data, '2');
              const defaultParams = getDefaultParams(matchFirst, provinceArr);
              callback && callback(defaultParams);
              setDefaultItem(defaultParams);
              setTreeData(treeData);

              setProvince(provinceArr);
            }
            setInitResult(data);
          } else {
            setErrorMsg('暂无权限');
          }
        } else {
          setErrorMsg(res.message);
        }
      })
      .catch(() => {
        setErrorMsg('系统异常');
      })
      .finally(() => {
        setInitLoading(false);
      });
  };

  useEffect(() => {
    init();
  }, []);

  return {
    initLoading,
    province,
    errorMsg,
    initResult,
    defaultItem,
    treeData,
  };
}

type Fn = (value?: any) => void;

// Power接口返回数据
export type PowerResType = {
  deptId: string;
  deptName: string;
  groupId: string;
  groupName: string;
  /**
   *  交易中心id
   */
  marketId: string;
  /**
   *  交易中心名称
   */
  marketName: string;
  /**
   *  省份id
   */
  provinceId: string;
  /**
   *  省份名称
   */
  provinceName: string;
  /**
   *  交易单元id
   */
  stationId: string;
  /**
   *  交易单元名称
   */
  stationName: string;
  stationType: number;
};

export type ProvinceType = {
  /**
   *  接口返回中的 marketId
   */
  value: string;
  /**
   *  接口返回中的 marketName
   */
  label: string;
  /**
   *  接口返回中的 省份Id
   */
  provinceId: string;
  /**
   *  接口返回中的 省份名称
   */
  provinceName: string;
  /**
   *  当前交易中心下所属 交易单元
   */
  stations: StationType[];
};

export type StationType = {
  /**
   *  交易单元id
   */
  stationId: string;
  /**
   *  交易单元名称
   */
  stationName: string;
  stationType: number;
  value?: any;
};

export type TreeDatatype = {
  title: string;
  key: string;
  children?: TreeDatatype[];
};

type useRequestPowerAfterInitOptinos = {
  /**
   *  是否转换数据传`0`或不传则直接从initResult获取初始化数据
   *  传入`1`则将数据转换到省份及所属场站
   *  传入`2`数据多返回一个treeData
   */
  convertResult?: '0' | '1' | '2';
  /**
   *  匹配默认值传入索引时通过索引去获取
   *  可以传入一个仿佛自行匹配
   */
  matchFirst?: number | ((arr: any[]) => any);
};

export { useRequestPowerAfterInit, convertResult, getDefaultParams };
